{% extends 'common/panel.html' %}
{% block title %}{{site.name}} - Create a Chart{% endblock title %}
{% block panel %}
<style type="text/css" media="screen">
    
  #newChart {
      margin:0;
      padding:0;
      margin-top:20px;
  }

  #createAChart {
    text-align:center;
    width:95%;
    height:310px;
    margin-left:auto;
    margin-right:auto;
  }
  
  #chartTaxa li {
      font-size:14px;
      padding:5px 0px;
      position:relative;
      margin-left:5px;
      width:410px;
  }
    
  #chartTaxa li span.legend {
      width:20px;
      height:10px;
      position:absolute;
      left:-30px;
      top:8px;
  }
  
  #chartTaxa .remove {
      position:absolute;
      right:0px;
  }
  
  #chartTaxa li.nodata .remove {
      display:none;
  }
  
  #chartTaxa li.nodata span.legend {
      background-color:#C0C0C0 !important;
  }
  
  #chartTaxa li em.nodata {
      display:none;
  }
  
  #chartTaxa li.nodata em.nodata {
      display:block;
  }
  
  
  #addTaxa {
      position:absolute;
      right:20px;
  }
  
  .chartspinner {
      position:absolute;
      right:130px;
      margin-top:-3px;
      display:none;
  }
  
  .chartTooltip {
      position:absolute;
      background-color:#FFF9E9;
      border:solid #9E9E9E 1px;
      z-index:50000;
      padding:5px;
  }
  
  .chartTooltip h4 {
      margin:0;
      padding:0;
  }
  
  .chartTooltip p {
      margin:0;
      padding:1px 0px;
      font-size:.9em;
  }
  
  p.mean {
      font-size:14px;
      font-weight:bold;
      color:#352A2A;
  }
  
  a.remove {
      color:#424C58;
/*      text-decoration:none;*/
/*      font-size:.8em;*/
  }
</style>
<script type="text/javascript" charset="utf-8">
    
    function pickName(d){
        return d.common_name || d.scientific_name;
    }
    
    var SiteTimeChart = function(chartEl, listEl, spinner){
        this.list = listEl;
        this.spinner = spinner;
        this.chart = d3.select(chartEl)
            .append("svg:svg")
                .attr("width", this.width)
                .attr("height", this.height)
        this.g = this.chart.append("svg:g")
            .attr("transform", "translate(0, "+this.height+")");
        
        this.line = d3.svg.line()
            .x(function(d,i) { return this.x(i); })
            .y(function(d) { return -1 * d; })
            
        this.tooltip = d3.select('body')
                          .append('div')
                              .attr('class', 'chartTooltip')
        
    }
    
    _.extend(SiteTimeChart.prototype, {

        width: 440,
        height: 300,
        margin: 20,
        'margin-left': 40,
        taxa: [],
        limit: 6,        
        x: d3.scale.linear(),
        y: {},
        lines: {},
        colorScale: d3.scale.category10(),
        
        addTaxon: function(data){
            if(this.taxa.length >= this.limit){
                alert('You cannot add more than ' + 
                    this.limit + ' taxa to the chart.');
                return;
            }
            if(!_.any(this.taxa, function(t){ return t.id === data.id; })){
                this.taxa.push(data);
                this.renderList();                
            }
            this.fetchRecords(data);
        },
        
        removeTaxon: function(id){
            // Remove taxon matching id from list
            this.taxa = _.select(this.taxa, 
                function(d){ return d.id !== id; });
            this.renderList();
            this.renderChart();
        },
        
        renderList: function(){
            // render list
            var elements = d3.select(this.list)
                .selectAll('li')
                    .data(this.taxa, function(d){ return d.id + d.protocol })
                    
            var that = this;
            
            var list_elements = elements.enter()
                .append('li')
                    .text(pickName)
                    .attr('data-taxon', function(d){d.list_element = this;return null;})
            
            list_elements
                    .append('a')
                        .attr('class', 'remove')
                        .text('remove')
                        .attr('href', '#')
                        .attr('data-id', function(d){ return d.id; })
                        .on('click', function(d){
                            that.removeTaxon(d.id);
                        })
            
            list_elements.append('span')
                .attr('class', 'legend')
                .text(' ')
                .style('background-color', function(d, i){ return that.colorScale(d.id); })
            
            list_elements.append('em')
                .attr('class', 'nodata')
                .text(' no data at this site')

            if($.browser.msie){
                elements.exit()
                    .remove()
                
            }else{
                // Only add transition if not IE
                elements.exit()
                    .style('background-color', '#EACBCF')
                    .transition()
                        .duration(200)
                        .style('opacity', function(d, i){ return i; })
                        .style('-moz-opacity', function(d, i){ return i; })
                        .style('-webkit-opacity', function(d, i){ return i; })
                        .remove()                
            }
                    
            if(this.taxa.length === 0){
                $('#newChart').show();
                $('#stddev').hide();
            }else{
                $('#newChart').hide();                
                $('#stddev').show();
            }
        },
        
        fetchRecords: function(taxon, cback){
            this.spin();
            var that = this;
            var url = taxon['records-url'].replace('99999999999', {{site.pk}});
            $.getJSON(url, function(data){
                that.unspin();
                taxon['records'] = data;
                if(data.length === 0){
                    $(taxon.list_element).addClass('nodata');
                    that.taxa.pop();
                }else{
                    that.renderChart();                    
                }
            });
        },
        
        yAxisX: function(i){
            return (25 * i) + (40 * (i + 1));
        },
        
        renderChart: function(){
            // Calculate min/max dates, unique units
            var all_records = _.flatten(_.pluck(this.taxa, 'records'));
            var years = _.pluck(all_records, 'year');
            var units = _.uniq(_.pluck(all_records, 'unit'));

            // Adjust x scale to account for y-axis labels
            var scale_margin = this.yAxisX(units.length - 1);
            this.x.range([0 + scale_margin + 15, this.width - this.margin])
                .domain([_.min(years), _.max(years)]);

            
            // Remove existing y-axis labels
            this.g.selectAll('.yAxis').remove();
            var that = this;
            _.each(units, function(unit, i){
                // Create a new scale for this unit
                var scale = that.y[unit] = d3.scale.linear().range(
                    [0 + that.margin, that.height - that.margin]);
                // Get all records using this scale
                var filtered = _.select(all_records, 
                    function(r){ return r.unit == unit });
                var means = _.pluck(filtered, 'mean');
                // Set min/max value for scale based on records
                scale.domain([0, 
                    // If scale is 0.0 - 0.0, set to 0.0 - 1.0
                    _.max(means) || 1]);

                var classname = unit.replace(/[^A-z]/g, '');                

                var majorTics = scale.ticks(4);
                // Add y-axis labels
                that.g.selectAll("."+classname)
                    .data(majorTics)
                    .enter().append('svg:text')
                        .attr('class', function(d){return classname + ' yLabels yAxis';})
                        // .attr('class', classname + ' yLabels yAxis')
                        .text(function(d){return (Math.round(d*100)/100).toString();})
                        .attr('x', that.yAxisX(i))
                        .attr('y', function(d){ return scale(d) * -1;})
                        .attr('text-anchor', 'end')
                        .style('text-align', 'right')
                        .style('width', '4em')
                        .attr("dy", 4)

                // Add y-xis major tics
                that.g.selectAll("."+classname+"Tic")
                    .data(majorTics)
                    .enter().append('svg:line')
                        .attr('class', classname+"Tic yAxis")
                        .attr('x1',that.yAxisX(i)+1)
                        .attr('x2', that.yAxisX(i)+6)
                        .attr('y1', function(d){return scale(d) * -1})
                        .attr('y2', function(d){return scale(d) * -1})
                        .style('stroke', 'black')                        
                
                that.g.append('svg:line')
                    .attr('class', 'yAxis')
                    .attr('x1', that.yAxisX(i) + 6)
                    .attr('x2', that.yAxisX(i) + 6)
                    .attr('y1', scale(_.max(means)) * -1)
                    .attr('y2', scale(0) * -1)
                    .style('stroke', '#AFB6BD')
                
                var x = that.yAxisX(i) - 30;
                var y = (that.height / 2) * -1;
                
                that.g.append('svg:text')
                    .attr('transform', 'rotate(-90 '+x+' '+y+')')
                    .attr('class', 'yTics unitLabel yAxis')
                    .text(unit)
                    .attr('x', x)
                    .attr('y', y)
                
                that.lines[unit] = d3.svg.line()
                    .x(function(d) { return that.x(d.year); })
                    .y(function(d) { return -1 * that.y[unit](d.mean); });
            });
            
            // Remove all components of existing x-axis labels
            this.g.selectAll(".xLabel, .xTic, .xAxis").remove();

            var majorTics = that.x.ticks(5);
            // Add year labels
            this.g.selectAll(".xLabel")
                .data(majorTics)
                .enter().append("svg:text")
                .attr("class", "xLabel")
                .text(String)
                .attr("x", that.x)
                .attr("y", 0)
                .attr("text-anchor", "middle")
                
            // Add "tic-line"
            this.g.selectAll(".xTic")
                .data(that.x.ticks(that.x.domain()[1] - that.x.domain()[0]))
                .enter().append('svg:line')
                    .attr('x1', that.x)
                    .attr('x2', that.x)
                    .attr('y1', function(d){return _.include(majorTics, d) ? -10 : -13;})
                    .attr('y2', -15)
                    .attr('class', 'xTic')
                    .style('stroke', 'black')

            if(all_records.length){
                this.g.append('svg:line')
                    .attr('class', 'xAxis')
                    .attr('x1', that.x.range()[0])
                    .attr('x2', that.x.range()[1])
                    .attr('y1', -15)
                    .attr('y2', -15)
                    .style('stroke', '#AFB6BD')                
            }

            // this.g.selectAll('path.taxon').remove();

            // add error bars
            this.g.selectAll('line.errorbar').remove()
            this.g.selectAll('line.errorbar')
                .data(all_records).enter().append('svg:line')
                    .attr('class', function(d){d.errorbar = this; return 'errorbar';})
                    .attr('x1', function(d){return that.x(d.year);})
                    .attr('x2', function(d){return that.x(d.year);})
                    .attr('y1', function(d){return -1 * that.y[d.unit](d.mean - d.stderror)})
                    .attr('y2', function(d){return -1 * that.y[d.unit](d.mean + d.stderror)})
                    .style('stroke', '#FFCAD7')
            
            var taxa = this.g.selectAll('path.taxon').remove();
            
            // Now render the data
            var taxa = this.g.selectAll('path.taxon')
                .data(this.taxa, function(d){ return d.id + d.protocol; })
                        
            taxa.enter().append('svg:path')
                .attr('class', 'taxon')
                .style('stroke', function(d){return that.colorScale(d.id);})
                .style('fill', 'none')
                .attr('d', function(d){ return that.lines[d.unit](d.records);})
            
            
            // Add dots
            this.g.selectAll('circle.record').remove();
            this.g.selectAll('circle.record')
                .data(all_records).enter().append('svg:circle')
                    .attr('class', 'record')
                    .attr('cx', function(d){return that.x(d.year);})
                    .attr('cy', function(d){return -1 * that.y[d.unit](d.mean)})
                    .attr('r', '3')
                    .style('stroke', 'white')
                    .style('fill', function(d){return that.colorScale(d.taxon);})
                    .on('mouseover', function(d, i){that.mouseover.apply(that, [this, d, i]);})
                    .on('mouseout', function(d, i){that.mouseout.apply(that, [this, d, i]);})
                    .style('cursor', 'pointer')        
                            
            
        },
        
        mouseover: function(el, d, i){
            $(this.tooltip[0]).html('<h4>'+pickName(d)+'</h4>'+'<p class="year">'+d.year+' - '+d.protocol+'</p><p class="mean">'+(Math.round(d.mean * 100)/100)+' '+d.unit_suffix+'</p>');
            var width = $(this.tooltip[0]).width();
            // For the benefit of good `ol IE
            var pageX = event.pageX || event.clientX;
            var pageY = event.pageY || event.clientY;
            if(pageX > 420 - width){
                this.tooltip.style("top", (pageY-10)+"px").style("left",(pageX-(width + 30))+"px");                                
            }else{
                this.tooltip.style("top", (pageY-10)+"px").style("left",(pageX+20)+"px");                
            }
            this.tooltip.style("display", 'block');
            d3.select(d.errorbar).style('stroke', '#FF4B4D')
            d3.select(el)
                .style('stroke', '#FFED25')
                .style('stroke-width', '3')
                .attr('r', 5)
        
        },
        
        mouseout: function(el, d, i){
            this.tooltip.style("display", 'none');
            d3.select(d.errorbar).style('stroke', '#FFCAD7')
            d3.select(el)
                .style('stroke', 'white')
                .style('stroke-width', '1')
                .attr('r', 3)
        },
        
        spin: function(){
            this.spinner.show();
        },
        
        unspin: function(){
            this.spinner.hide();
        },
        
        destroy: function(){
            this.tooltip.remove();
        }
    });
    
</script>
<script type="text/javascript" charset="utf-8">
    $('#search_panel a.close').click();
    lingcod.onShow(function(){
        $('#addTaxa').unbind('click');
        
        moveSearchToForeground();
        
        if(window.supportsSvg){
            var chart;
            function setupChart(){
                chart = new SiteTimeChart(
                    $('#createAChart')[0], $('#chartTaxa')[0], $('.chartspinner'));            
            }

            // if(window.svgweb){
            //     window.onsvgload = setupChart;
            // }else{
                setupChart();
            // }

            setSearchChoiceCallback(function(choice){
                $('#search_panel a.close').click()
                chart.addTaxon(choice.data());
            });        

            $('#addTaxa').click(function(){
                var href = "{% url monitoring.views.search 1 %}";
                search_panel.showUrl(href, {});
            });            
        }else{
            $('#addTaxa').hide();
            d3.select('#createAChart')
                .append('p')
                    .attr('class', 'unsupported')
                    .html('This interactive chart requires a modern browser that supports SVG. To see it, please visit this site using <a href="http://www.google.com/chrome" title="Google Chrome - Get a fast new browser. For PC, Mac, and Linux">Google Chrome</a>, <a href="http://www.mozilla.com/en-US/firefox/new/" title="Mozilla Firefox Web Browser — Free Download">Firefox</a>, or <a href="http://www.ie9enhanced.com">Internet Explorer 9</a>.')
        }
        
        
    });
    
    lingcod.beforeDestroy(function(){
        moveSearchToBackground();
        clearSearchChoiceCallback();
    });
    
</script>

  {% if not is_ajax and not request.is_ajax %}
    <h1>{{site.name}} - Create a Chart</h1>
  {% endif %}

  <div id="createAChart">
      <img id="newChart" src="{{MEDIA_URL}}images/new_chart.png" width="300" height="300">
  </div>
  <ul id="chartTaxa">
  </ul>
  <hr>
  <img class="chartspinner" src="{{MEDIA_URL}}common/images/ajax-loader.gif" width="32" height="32">
  <a id="addTaxa" href="#" class="button" onclick="this.blur(); return false;">
    <span>Add Taxa</span>
  </a>
  <p style="display:none;" id="stddev">* red vertical lines indicate standard deviation.</p>
{% endblock panel %}